Skip to content

Conversation

cdce8p
Copy link
Contributor

@cdce8p cdce8p commented Sep 17, 2025

This PR complements and extends the work done in #138915.

In a microbenchmark for bare class matches, the match statement is now even slightly faster than the comparable if statement. With keyword only patterns, the performance is much improved as it's no longer necessary to construct intermediary tuples so that's now only ~20% slower compared to the if equivalent. (Previously it was closer to ~220%).

Further improvements can likely be archived if MATCH_CLASS_GET_OPT_ATTR is specialized in a similar manner to LOAD_ATTR. With the specialization for (just) LOAD_ATTR disabled, the match statement equivalent is again slightly faster than the corresponding if clause.

__
Micro benchmarks with all specializations enabled.

Micro benchmark (bare class pattern)
from timeit import timeit
setup = """
class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y
a = A(1, 2)

def f1(a):
    if isinstance(a, A):
        return True
    return False

def f2(a):
    match a:
        case A():
            return True
    return False
"""
print(f"If\t{timeit("f1(a)", setup, number=10**7)}")
print(f"Match\t{timeit("f2(a)", setup, number=10**7)}")
# Before
If      0.29646458296338096
Match   0.6549855829798616

# After
If      0.2934637920006935
Match   0.2751032500018482 -> -58%
Micro benchmark (One keyword attribute)
from timeit import timeit
setup = """
class A:
    def __init__(self, x, y):
        self.x = x
        self.y = y
a = A(1, 2)

def f1(a):
    if isinstance(a, A) and a.x == 1:
        return True
    return False

def f2(a):
    match a:
        case A(x=1):
            return True
    return False
"""
print(f"If\t{timeit("f1(a)", setup, number=10**7)}")
print(f"Match\t{timeit("f2(a)", setup, number=10**7)}")
# Before
If      0.35557704203529283
Match   1.1494590829825029

# After
If      0.3604730829974869
Match   0.45169049999822164  -> -61%

📚 Documentation preview 📚: https://cpython-previews--139080.org.readthedocs.build/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant